#include <iostream>
#include <string>
#include <vector>
#include <cassert>
#include <unistd.h>//一般系统文件用.h 
#include "Task.hpp"

using namespace std;

const int gnum = 5;//创建子进程的个数
Task t;

class EndPoint
{
public:
    pid_t _child_id;
    int _write_fd;
public:
    EndPoint(int id,int fd)
    :_child_id(id)
    ,_write_fd(fd)
    {}
    ~EndPoint()
    {}
};
//子进程要执行的方法
void WaitCommand()
{
    while(true)
    {
        int command = 0;
        int n = read(0,&command,sizeof(int));
        if(n == sizeof(int))
        {
            t.Execute(command);
        }
        else if(n == 0)
        {
            break;
        }
        else
        {
            break;
        }
    }

}

void createProcesses(vector<EndPoint>* end_points)
{
    for(int i = 0;i < gnum; i++)
    {
        // 1.1 创建管道
        int pipefd[2] = {0};
        int n = pipe(pipefd);
        assert(n == 0);
        (void)n;

        // 1.2 创建进程
        pid_t id = fork();
        assert(id != -1);
        //一定是子进程
        if(id == 0) 
        {
            // 1.3 关闭不要的fd
            close(pipefd[1]);//关闭写入
            // 我们期望，所有紫禁城读取“指令”的时候，都从标准输入读取
            // 1.3.1 输入重定向
            dup2(pipefd[0],0);
            // 1.3.2 子进程开始等待获取命令
            WaitCommand();
            
            close(pipefd[0]);//结束了关闭读
            exit(0);
        }
        //一定是父进
        // 1.3 关闭不要的fd
        close(pipefd[0]);//关闭读

        // 1.4 将新的子进程和他的管道写端，构建对象
        end_points->push_back(EndPoint(id,pipefd[1]));


    }

}

int main()
{
    // 1. 先构建控制结构,父进程写入1，子进程读取0
    vector<EndPoint> end_points;
    createProcesses(&end_points);
    // 2. 我们的到了什么
    int num = 0;
    cout<<"执行到while了"<<endl;
    while(true)
    {
        // 1. 选择任务
        //cout<<"执行到选择任务"<<endl;
        int command = COMMAND_LOG;
        //cout<<"选择任务执行完毕！"<<endl;

        // 2. 选择进程
        //cout<<"执行到选择进程"<<endl;
        int index = rand()%end_points.size();
        //cout<<"选择进程执行完毕！"<<endl;
        // cout<< "index:"<<index<<endl;


        // 3. 下发任务 
        //cout<<"执行到下发任务"<<endl;
        write(end_points[index]._write_fd,&command,sizeof(command));
        //<<"下发任务执行完毕！"<<endl;

        sleep(1);
    }
    return 0;
}